package com.suns.service;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.suns.dao.SysDeptMapper;
import com.suns.dto.DeptLevelDto;
import com.suns.model.SysDept;
import com.suns.util.LevelUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

// 计算树结构接口    Multimap**
@Service
public class SysTreeService {

    @Resource
    private SysDeptMapper sysDeptMapper;

    /**
     * 对传进来的 当前层级list，level，map(辅助) ，进行递归排序
     * @param deptLevelList
     * @param level
     * @param levelDeptMap
     */
    public void transformDeptTree(List<DeptLevelDto> deptLevelList, String level, Multimap<String, DeptLevelDto> levelDeptMap) {
        //遍历当前层list
        for (int i = 0; i < deptLevelList.size(); i++) {
            // 获取当前层每个元素
            DeptLevelDto dto = deptLevelList.get(i);

            // (便于处理下一层次数据) 下一层的level
            String nextLevel = LevelUtil.calculateLevel(level,dto.getId());

            // 下一层的数据list
            List<DeptLevelDto> temDeptList = (List<DeptLevelDto>) levelDeptMap.get(nextLevel);

            // 判断下一层数据是否非空
            if (CollectionUtils.isNotEmpty(temDeptList)) {
                // 非空代表下一层有数据
                // 下一层数据排序
                Collections.sort(temDeptList,deptSeqComparator);
                // 将下一层的数据存入部门内
                dto.setDeptList(temDeptList);

                // 递归，调用当前方法，将此层的下一层作为上层，获取下一层数据
                transformDeptTree(temDeptList, nextLevel, levelDeptMap);
            }

        }
    }

    /**
     * 自定义部门排序方法 （按照seq从小到大排序）
     */
    public Comparator<DeptLevelDto> deptSeqComparator = new Comparator<DeptLevelDto>() {
        @Override
        public int compare(DeptLevelDto o1, DeptLevelDto o2) {
            return o1.getSeq() - o2.getSeq();
        }
    };

    /**
     * 获取一级层级
     * @param deptLevelList
     * @return
     */
    public List<DeptLevelDto> deptListToTree(List<DeptLevelDto> deptLevelList) {
        // 如果dtoList为空
        if (CollectionUtils.isEmpty(deptLevelList)) {
            // 当前dept无值返回无值的List
            return Lists.newArrayList();
        }

        // 获取跟部门list  以它为起点
        List<DeptLevelDto> rootList = Lists.newArrayList();

        // 即Map<String, List<DeptLevelDto>> 非空，代表有值，定义特殊数据结构  level -> [dept1, dept2, ...]   以它为辅助数据
        Multimap<String, DeptLevelDto> levelDeptMap = ArrayListMultimap.create();

        // 获取一级部门
        // 遍历deptLevelList，将值存入levelDeptMap内
        for (DeptLevelDto dto : deptLevelList) {
            //key: dto.level   value:dto
            levelDeptMap.put(dto.getLevel(), dto);

            //每遍历一个dto,判断level是否与LevelUtil的ROOT相等，相等代表是根部门
            if (LevelUtil.ROOT.equals(dto.getLevel())) {
                rootList.add(dto);
            }
        }
        // 以rootList为起点，以levelDeptMap为辅助，组装部门树
        // 按照seq从小到大排序 自定义排序
        Collections.sort(rootList, deptSeqComparator);

        // 当前rootList已排序，要对rootList下的进行递归排序  递归生成树
        transformDeptTree(rootList,LevelUtil.ROOT,levelDeptMap);

        return rootList;
    }


    /**
     * 获取项目下的所有部门树
     * @return
     */
    public List<DeptLevelDto> deptTree() {
        // 1.获取部门表下的所有部门
        List<SysDept> deptList = sysDeptMapper.getAllDept();

        // 2.创建一个DeptLevelDto集合(google guava 的集合类Lists)
        List<DeptLevelDto> dtoList = Lists.newArrayList();

        // 3.获取部门的dtoList数据
        // 遍历SysDept集合
        for (SysDept dept : deptList) {
            // 调用DeptLevelDto内的 adapt方法，将SysDept适配成 DeptLevelDto
            DeptLevelDto dto = DeptLevelDto.adapt(dept);
            // 将dto存入到DeptLevelDto集合内
            dtoList.add(dto);
        }

        // 4.将dtoList做成树形结构
        return deptListToTree(dtoList);
    }


}
